package com.neusoft.neuiotms.dcom.service.problem.impl;

import java.util.Date;

import javax.persistence.EntityNotFoundException;
import javax.transaction.Transactional;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.neusoft.bizcore.activiti.enums.WorkOrderStatus;
import com.neusoft.bizcore.activiti.service.ProcessInstanceService;
import com.neusoft.bizcore.auth.common.bean.UserBean;
import com.neusoft.bizcore.web.constant.ExceptionConstants;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.neuiotms.dcom.converter.problem.ProblemConfirmationConverter;
import com.neusoft.neuiotms.dcom.dto.change.ChangeRegistrationDTO;
import com.neusoft.neuiotms.dcom.dto.problem.ProblemConfirmationDTO;
import com.neusoft.neuiotms.dcom.dto.problem.ProblemRegistrationDTO;
import com.neusoft.neuiotms.dcom.model.enums.ProblemConfirmationOperationEnum;
import com.neusoft.neuiotms.dcom.model.problem.ProblemConfirmation;
import com.neusoft.neuiotms.dcom.repository.problem.ProblemConfirmationRepository;
import com.neusoft.neuiotms.dcom.service.change.ChangeRegistrationService;
import com.neusoft.neuiotms.dcom.service.problem.ProblemConfirmationService;
import com.neusoft.neuiotms.dcom.service.problem.ProblemRegistrationService;

@Service
public class ProblemConfirmationServiceImpl implements ProblemConfirmationService {

    @Autowired
    private ProblemConfirmationRepository problemConfirmationRepository;

    @Autowired
    private ProblemConfirmationConverter problemConfirmationConverter;

    @Autowired
    private ProcessInstanceService processInstanceService;

    @Autowired
    private ProblemRegistrationService problemRegistrationService;

    @Autowired
    private ChangeRegistrationService changeRegistrationService;

    @Override
    @Transactional
    public ProblemConfirmationDTO create(final ProblemConfirmationDTO dto, final UserBean user) {
        this.processInstanceService.setGlobalVariable(dto.getTaskId(), "problemConfirmationOperation",
                dto.getOperation());
        if (dto.getOperation().name().equals(ProblemConfirmationOperationEnum.change.name())) {
            // 调用变更接口
            final ProblemRegistrationDTO problemDTO =
                    this.problemRegistrationService.findByWorkNum(dto.getWorkOrderNum());
            if (problemDTO != null) {
                final ChangeRegistrationDTO changeDTO = new ChangeRegistrationDTO();
                changeDTO.setApplicant(problemDTO.getApplicant());
                changeDTO.setApplicationType(problemDTO.getApplicationType());
                changeDTO.setCiId(problemDTO.getCiCode());
                changeDTO.setCiId(problemDTO.getCiId());
                changeDTO.setCiCode(problemDTO.getCiCode());
                changeDTO.setCiName(problemDTO.getCiName());
                changeDTO.setContactInformation(problemDTO.getContactInformation());
                changeDTO.setExecutorCode(problemDTO.getExecutorCode());
                changeDTO.setExecutor(problemDTO.getExecutor());
                changeDTO.setInfluenceCoverage(problemDTO.getInfluenceCoverage());
                changeDTO.setPriority(problemDTO.getPriority());
                changeDTO.setUrgencyDegree(problemDTO.getUrgencyDegree());
                changeDTO.setRegistrantCode(problemDTO.getRegistrantCode());
                changeDTO.setRegistrant(problemDTO.getRegistrant());
                changeDTO.setSource("PROBLEM_STUDY");
                changeDTO.setStatus(WorkOrderStatus.temporary.name());
                changeDTO.setTitle(problemDTO.getTitle());
                changeDTO.setApplicationTime(new Date());
                changeDTO.setDescription(problemDTO.getDescription());

                this.changeRegistrationService.create(changeDTO, user);
            }
        }
        // 查询当前workNum和TaskId下是否存在记录
        final ProblemConfirmation oldModel = this.problemConfirmationRepository.findByWorkOrderNumAndTaskId(
                dto.getWorkOrderNum(), dto.getTaskId());
        if (oldModel == null) { // 如果不存在新增
            dto.setId(null);
        }

        final ProblemConfirmation model = this.problemConfirmationConverter.toModel(dto);
        this.problemConfirmationRepository.save(model);

        // 完成节点
        this.processInstanceService.complete(dto.getWorkOrderNum(), dto.getTaskId(), user);

        return this.problemConfirmationConverter.toDTO(model);
    }

    @Override
    public ProblemConfirmationDTO detail(final String workOrderNum, final String taskId, final UserBean user) {
        ProblemConfirmation model = null;
        try {
            if (StringUtils.isNotBlank(workOrderNum) && !"NULL".equals(taskId)) {
                model = this.problemConfirmationRepository.findByWorkOrderNumAndTaskId(workOrderNum, taskId);
                if (model == null) {
                    // 获取前一节点的TaskID
                    final String lastTaskId = this.processInstanceService.getLastTaskId(taskId, user);
                    if (lastTaskId == null) {
                        return new ProblemConfirmationDTO();
                    } else {
                        model = this.problemConfirmationRepository.findByWorkOrderNumAndTaskId(workOrderNum,
                                lastTaskId);
                    }
                }
            } else if ("NULL".equals(taskId)) {
                model = this.problemConfirmationRepository.findByWorkOrderNum(workOrderNum);
            }
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND,
                    new Object[] {workOrderNum },
                    new Object[] {taskId });
        }
        return this.problemConfirmationConverter.toDTO(model);
    }

    @Override
    public ProblemConfirmationDTO findByWorkOrderNumAndTaskId(final String workOrderNum, final String taskId) {
        final ProblemConfirmation model =
                this.problemConfirmationRepository.findByWorkOrderNumAndTaskId(workOrderNum, taskId);
        return this.problemConfirmationConverter.toDTO(model);
    }

    @Override
    public void deleteByWorkOrderNum(final String workOrderNum) {
        this.problemConfirmationRepository.deleteByWorkOrderNum(workOrderNum);
    }

}
